package com.styletransfer.service;

import com.aliyun.oss.OSS;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectRequest;
import com.styletransfer.config.AliyunOssConfig;
import com.styletransfer.exception.BusinessException;
import com.styletransfer.model.ApiResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * 阿里云OSS服务类
 */
@Slf4j
@Service
public class OssService {
    @Autowired
    private OSS ossClient;

    @Autowired
    private AliyunOssConfig ossConfig;

    /**
     * 上传图片到OSS
     * @param file 图片文件
     * @param dirType 存储目录类型（image, style, result）
     * @return 上传结果
     */
    public ApiResponse<Map<String, Object>> uploadImage(MultipartFile file, String dirType) {
        if (file == null || file.isEmpty()) {
            return ApiResponse.error("上传文件不能为空");
        }

        // 获取文件名
        String originalFilename = file.getOriginalFilename();

        // 校验文件类型
        String fileExtension = getFileExtension(originalFilename);
        if (!isAllowedExtension(fileExtension)) {
            return ApiResponse.error("不支持的文件类型，仅支持jpg、jpeg、png、gif格式");
        }

        // 生成新的文件名
        String newFilename = generateFilename(fileExtension);

        // 确定存储目录
        String dir = getDir(dirType);

        // 构建OSS文件路径
        String ossFilePath = dir + newFilename;

        try {
            // 获取文件输入流
            InputStream inputStream = file.getInputStream();

            // 创建上传Object的元数据
            ObjectMetadata metadata = new ObjectMetadata();
            // 设置Content-Type
            metadata.setContentType(getContentType(fileExtension));
            // 设置文件大小
            metadata.setContentLength(file.getSize());

            // 上传文件
            PutObjectRequest putObjectRequest = new PutObjectRequest(
                    ossConfig.getBucketName(), ossFilePath, inputStream, metadata);
            ossClient.putObject(putObjectRequest);

            // 构建访问URL
            String imageUrl = ossConfig.getUrlPrefix() + ossFilePath;

            // 构建返回结果
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("imageId", newFilename);
            resultMap.put("imageUrl", imageUrl);
            resultMap.put("size", file.getSize());
            resultMap.put("filename", originalFilename);

            return ApiResponse.success(resultMap);
        } catch (IOException e) {
            log.error("上传图片到OSS失败", e);
            return ApiResponse.error("上传图片失败: " + e.getMessage());
        }
    }

    /**
     * 从OSS删除文件
     * @param fileUrl 文件URL或路径
     * @return 是否删除成功
     */
    public boolean deleteFile(String fileUrl) {
        if (fileUrl == null || fileUrl.isEmpty()) {
            return false;
        }
        
        try {
            // 如果是完整URL，需要提取出OSS对象的key
            String objectKey = fileUrl;
            
            // 检查是否是完整的URL路径（包含URL前缀）
            if (fileUrl.startsWith(ossConfig.getUrlPrefix())) {
                objectKey = fileUrl.substring(ossConfig.getUrlPrefix().length());
            }
            
            // 删除OSS对象
            ossClient.deleteObject(ossConfig.getBucketName(), objectKey);
            log.info("成功删除OSS文件: {}", objectKey);
            return true;
        } catch (Exception e) {
            log.error("删除OSS文件失败: {}", fileUrl, e);
            return false;
        }
    }

    /**
     * 获取文件扩展名
     * @param filename 文件名
     * @return 扩展名
     */
    private String getFileExtension(String filename) {
        if (filename == null || filename.lastIndexOf(".") == -1) {
            return "";
        }
        return filename.substring(filename.lastIndexOf(".") + 1).toLowerCase();
    }

    /**
     * 检查文件扩展名是否允许
     * @param extension 扩展名
     * @return 是否允许
     */
    private boolean isAllowedExtension(String extension) {
        String[] allowedExtensions = {"jpg", "jpeg", "png", "gif"};
        for (String allowed : allowedExtensions) {
            if (allowed.equalsIgnoreCase(extension)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 生成新的文件名
     * @param extension 扩展名
     * @return 新文件名
     */
    private String generateFilename(String extension) {
        // 生成UUID
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
        // 添加时间戳
        String timestamp = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
        // 组合新文件名
        return uuid + "_" + timestamp + "." + extension;
    }

    /**
     * 根据类型获取存储目录
     * @param dirType 目录类型
     * @return 存储目录
     */
    private String getDir(String dirType) {
        if ("style".equalsIgnoreCase(dirType)) {
            return ossConfig.getDir().getStyle();
        } else if ("result".equalsIgnoreCase(dirType)) {
            return ossConfig.getDir().getResult();
        } else {
            return ossConfig.getDir().getImage();
        }
    }

    /**
     * 获取文件的Content-Type
     * @param extension 扩展名
     * @return Content-Type
     */
    private String getContentType(String extension) {
        if ("jpg".equalsIgnoreCase(extension) || "jpeg".equalsIgnoreCase(extension)) {
            return "image/jpeg";
        } else if ("png".equalsIgnoreCase(extension)) {
            return "image/png";
        } else if ("gif".equalsIgnoreCase(extension)) {
            return "image/gif";
        }
        return "application/octet-stream";
    }

    /**
     * 上传文件到OSS并返回URL路径
     * @param file 文件
     * @param dirType 目录类型
     * @return 文件URL路径
     */
    public String uploadFile(MultipartFile file, String dirType) {
        ApiResponse<Map<String, Object>> response = uploadImage(file, dirType);
        if (response.getCode().equals(200)) {
            return (String) response.getData().get("imageUrl");
        } else {
            throw new BusinessException(response.getMessage());
        }
    }

    /**
     * 上传本地文件到OSS并返回URL路径
     * @param file 本地文件
     * @param dirType 目录类型
     * @return 文件URL路径
     */
    public String uploadFile(File file, String dirType) {
        if (file == null || !file.exists()) {
            throw new BusinessException("上传文件不能为空");
        }
        
        try {
            // 获取文件名
            String originalFilename = file.getName();
            
            // 校验文件类型
            String fileExtension = getFileExtension(originalFilename);
            if (!isAllowedExtension(fileExtension)) {
                throw new BusinessException("不支持的文件类型，仅支持jpg、jpeg、png、gif格式");
            }
            
            // 生成新的文件名
            String newFilename = generateFilename(fileExtension);
            
            // 确定存储目录
            String dir = getDir(dirType);
            
            // 构建OSS文件路径
            String ossFilePath = dir + newFilename;
            
            // 上传文件
            ossClient.putObject(ossConfig.getBucketName(), ossFilePath, file);
            
            // 构建访问URL
            String imageUrl = ossConfig.getUrlPrefix() + ossFilePath;
            
            return imageUrl;
        } catch (Exception e) {
            log.error("上传文件到OSS失败", e);
            throw new BusinessException("上传文件失败: " + e.getMessage());
        }
    }
}
